#include<iostream>
#include "star.h"
#include <windows.h>
#include <algorithm>
#include <string>
#include<conio.h>
#pragma once
//**********************************************************//
//文件功能：界面
//开发人员：小罗
//开发时间：2022.01.01
//开发内容：1.void ShowBeginPage();
//开发内容：2.void ShowCharacterPage();
//开发内容：3.void ShowGamePage();
//开发内容：4.void ShowRankPage();
//         
//**********************************************************//



using namespace std;

int mapWidth = 6;
int mapHeight = 4;
std::string player_name;

//光标移动函数
void gotoXY(int x, int y)//x就是横坐标从1开始，y就是纵坐标从1开始
{
    COORD c;
    c.X = x - 1;
    c.Y = y - 1;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}

//画横线函数，
//参数：起始坐标，终止坐标
//返回值：无
void DrawHorizontalLine(int x1, int y1, int x2, int y2) {
    if (y1 != y2 || y1 < 1 || y2 < 1 || x1 < 1 || x2 < 1) {
        cout << "wrong paramenters" << endl;
    }
    int LineLength = abs(x1 - x2);
    int StartPoint = x1;
    if (x2 < x1) StartPoint = x2;
    //开始画横线
    gotoXY(StartPoint, y1);//跳转光标位置
    for (int i = 0; i < LineLength; i++) {
        if (!i || i == LineLength) cout << "+";
        else cout << "-";
    }

}


//画五角星函数
void DrawFive(int x, int y) {
    gotoXY(x, y);
    cout << "         *         " << endl;
    gotoXY(x, y + 1);
    cout << "        ***        " << endl;
    gotoXY(x, y + 2);
    cout << "       *****       " << endl;
    gotoXY(x, y + 3);
    cout << "*******************" << endl;
    gotoXY(x, y + 4);
    cout << "   *************   " << endl;
    gotoXY(x, y + 5);
    cout << "     *********     " << endl;
    gotoXY(x, y + 6);
    cout << "    ****   ****    " << endl;
    gotoXY(x, y + 7);
    cout << "   **         **    " << endl;
    gotoXY(x, y + 8);
    cout << "  *             *   " << endl;
}

//画竖线函数
void DrawVerticalLine(int x1, int y1, int x2, int y2) {
    if (x1 != x2 || y1 < 1 || y2 < 1 || x1 < 1 || x2 < 1) {
        cout << "wrong parameters";
    }
    int LineLength = abs(y1 - y2);
    int StartPoint = y1;
    if (y2 < y1) StartPoint = y2;
    //开始画垂直线

    for (int i = 0; i <= LineLength; i++) {
        gotoXY(x1, StartPoint + i);//因为画垂直线所以要每次跳转光标
        if (!i || i == LineLength) cout << "+";
        else  cout << "|";

    }

}



class Rect//矩形方框类
{
public:
    int width;//矩形框的宽
    int height;//矩形框的高
    int startX1;
    int endX2;
    int startY1;
    int endY2;

    //构造函数
    Rect(int width, int height, int startX1, int endX2, int startY1, int endY2)
    {
        this->width = width;
        this->height = height;
        this->startX1 = startX1;
        this->endX2 = endX2;
        this->startY1 = startY1;
        this->endY2 = endY2;
    }
    Rect(int x1, int y1, int x2, int y2) {
        //(x1,y1)起始坐标，(x2,y2)斜对角坐标
        startX1 = x1;
        endX2 = x2;
        startY1 = y1;
        endY2 = y2;
        width = abs(x1 - x2) + 1;
        height = abs(y1 - y2) + 1;
    }
    ~Rect() {}

    void draw() {
        //两条横线，两条垂直线
        DrawHorizontalLine(startX1, startY1, endX2, startY1);
        DrawHorizontalLine(startX1, endY2, endX2, endY2);
        DrawVerticalLine(startX1, startY1, startX1, endY2);
        DrawVerticalLine(endX2, startY1, endX2, endY2);
    }

    void printText(std::string s) {
        //功能在矩形内沿一条横线打印文本，一个汉字占两个位置
        int textLength = s.size() >> 1;
        int emptyWidth = (width - 2) >> 1;//矩形空白能装汉字的宽度
        int emptyHeight = (height - 2);//矩形空白能装汉字的高度，即行数

        int textLines = s.size() / (width - 2);//记录文本需要的行数


        if (textLines > emptyHeight) cout << "the length of text is too long" << endl;

        for (int i = 0; i <= textLines; i++) {
            std::string tmp = s.substr(i * emptyWidth * 2, emptyWidth * 2);
            gotoXY(startX1 + 1, startY1 + i + 1);
            cout << tmp;
        }
    }

    void printText(std::string s, std::string position) {
        //重载printText函数
        //position 代表文字的位置 可以居中（midlle）
        //仅限对一行文字使用
        int textLength = s.size() >> 1;
        int emptyWidth = (width - 2) >> 1;//矩形空白能装汉字的宽度
        int emptyHeight = (height - 2);//矩形空白能装汉字的高度，即行数

        int textLines = s.size() / (width - 2);//记录文本需要的行数

        if (position == "middle") {
            if (textLines > 0) cout << "can not be middle" << endl;
            int printPosiX = startX1 + ((width - 2 - s.size()) >> 1);
            int printPosiY = startY1 + ((height - 1) >> 1);
            gotoXY(printPosiX + 1, printPosiY);
            cout << s;
        }
    }

};

class horizontalRectMadeByRect
{
public:
    int startX;
    int endX;
    int startY;
    int endY;
    int num;

    horizontalRectMadeByRect(int x1, int y1, int x2, int y2, int number) {
        startX = x1;
        startY = y1;
        endX = x2;
        endY = y2;
        num = number;
    }
    //画图
    void draw() {
        if ((endX - startX + 1) != mapWidth * num - num + 1) cout << "wrong parameter";
        for (int i = 0; i < num; i++) {
            gotoXY(startX + (mapWidth - 1) * i, startY);
            Rect tmp = Rect(startX + (mapWidth - 1) * i, startY, startX + (mapWidth - 1) * (i + 1), endY);
            tmp.draw();
        }
    }

    //输入文本
    //将所有要输入的文本组成一个字符串，如果有的格子不放事件，用八个空格代替
    void drawAndPrintText(int n, std::string s) {
        if (n * 4 * 2 != s.size()) cout << "input wrong length of text";
        for (int i = 0; i < num; i++) {
            Rect tmp = Rect(startX + (mapWidth - 1) * i, startY, startX + (mapWidth - 1) * (i + 1), endY);
            tmp.draw();
            tmp.printText(s.substr(8 * i, 8));
        }

    }


};


class verticalRectMadeByRect
{
public:
    int startX;
    int endX;
    int startY;
    int endY;
    int num;

    verticalRectMadeByRect(int x1, int y1, int x2, int y2, int number) {
        startX = x1;
        startY = y1;
        endX = x2;
        endY = y2;
        num = number;
    }
    void draw() {
        if ((endY - startY + 1) != mapHeight * num - num + 1) cout << "wrong parameter";
        for (int i = 0; i < num; i++) {
            gotoXY(startX, startY + (mapHeight - 1) * i);
            Rect tmp = Rect(startX, startY + (mapHeight - 1) * i, endX, startY + (mapHeight - 1) * (i + 1));
            tmp.draw();
        }
    }
    //输入文本
    //将所有要输入的文本组成一个字符串，如果有的格子不放事件，用八个空格代替
    void drawAndPrintText(int n, std::string s) {
        if ((endY - startY + 1) != mapHeight * num - num + 1) cout << "wrong parameter";
        for (int i = 0; i < num; i++) {
            gotoXY(startX, startY + (mapHeight - 1) * i);
            Rect tmp = Rect(startX, startY + (mapHeight - 1) * i, endX, startY + (mapHeight - 1) * (i + 1));
            tmp.draw();
            tmp.printText(s.substr(8 * i, 8));
        }
    }
};

class playerRect
{
public:
    int startX;
    int endX;
    int startY;
    int endY;
    //Player player;

    playerRect(int x1, int y1, int x2, int y2) {//,Player p){
        startX = x1;
        startY = y1;
        endX = x2;
        endY = y2;
        //player = p;
    }
    void draw() {//画框函数
        Rect playerName = Rect(startX, startY, endX, startY + 2);
        playerName.draw();

        Rect starNumRect = Rect(startX, startY + 2, startX + 11, startY + 6);
        starNumRect.draw();
        starNumRect.printText("星星数");
        //starNumRect.printText(to_string(p.star_num),"middle");

        //拥有骰子种类和数目
        Rect touzi = Rect(startX + 11, startY + 2, endX, startY + 6);
        touzi.draw();
        touzi.printText("touzi");

        Rect toolRect = Rect(startX, startY + 6, endX, startY + 13);
        toolRect.draw();
        toolRect.printText("道具栏");
        // std::string allLoots;
        // for(int i = 0;i<20;i++){
        //     if(*(p.loots[i])->loot_name) {
        //         allLoots += *(p.loots[i])->loot_name;
        //         allLoots += '/';
        //     }
        // }
        // toolRect.printText(allLoots,"middle"); 

        Rect partnerRect = Rect(startX, startY + 13, endX, endY);
        partnerRect.draw();
        partnerRect.printText("伙伴栏");
        // std::string allPartner;
        // for(int i = 0;i<20;i++){
        //     if(p.partner[i]) {
        //         allPartner += to_string(p.partner[i]);
        //         allPartner += '/';
        //     }
        // }
        // partnerRect.printText(allPartner,"middle");
    }

    void drawAndPrintText(Player p) {//玩家状态信息框
        Rect playerName = Rect(startX, startY, endX, startX + 2);
        playerName.draw();
        playerName.printText(p.name, "middle");

        Rect starNumRect = Rect(startX, startY + 2, startX + 11, startY + 6);
        starNumRect.draw();
        starNumRect.printText("星星数");
        starNumRect.printText(to_string(p.star_num), "middle");

        Rect toolRect = Rect(startX, startY + 6, endX, startY + 13);
        toolRect.draw();
        toolRect.printText("道具栏");
        std::string allLoots;
        // for(int i = 0;i<20;i++){
        //     if(*(p.loots[i])->loot_name) {
        //         allLoots += *(p.loots[i])->loot_name;
        //         allLoots += '/';
        //     }
        // }
        toolRect.printText(allLoots, "middle");

        Rect partnerRect = Rect(startX, startY + 13, endX, endY);
        partnerRect.draw();
        partnerRect.printText("伙伴栏");
        // std::string allPartner;
        // for(int i = 0;i<20;i++){
        //     if(p.partner[i]) {
        //         allPartner += to_string(p.partner[i]);
        //         allPartner += '/';
        //     }
        // }
        // partnerRect.printText(allPartner,"middle");
    }
};

class localRankRect : public horizontalRectMadeByRect
{
public:

    localRankRect(int x1, int y1, int x2, int y2, int number) :horizontalRectMadeByRect(x1, y1, x2, y2, number) {}
    //信息输入要看 排名数组的具体结构
    void drawAndPrintText(int _round, int _now_round, int rankid[]) {
        for (int i = 0; i < num; i++) {
            Rect tmp = Rect(startX + (mapWidth - 1) * i, startY, startX + (mapWidth - 1) * (i + 1), endY);
            tmp.draw();
            if (!i) {
                string msg;//记录全局总数与当前回合数
                msg += to_string(_now_round);
                msg += " / ";
                msg += to_string(_round);
                tmp.printText(msg);
            }
            else if (i == 1) tmp.printText("当前排名");
            else tmp.printText(to_string(rankid[i - 2]));
        }

    }

};

class characterListRect : public verticalRectMadeByRect
{
public:
    characterListRect(int x1, int y1, int x2, int y2, int number) : verticalRectMadeByRect(x1, y1, x2, y2, number) {}
    void drawAndPrintText(int n, Character* cha[]) {
        //n是画的竖条格子数，包括`人物列表`这个格子
        if ((endY - startY + 1) != mapHeight * num - num + 1) cout << "wrong parameter";
        for (int i = 0; i < num; i++) {
            gotoXY(startX, startY + (mapHeight - 1) * i);
            Rect tmp = Rect(startX, startY + (mapHeight - 1) * i, endX, startY + (mapHeight - 1) * (i + 1));
            tmp.draw();
            if (!i) tmp.printText("人物列表", "middle");
            else tmp.printText(cha[i - 1]->character_name);
        }

    }


};

class characterInfoRect
{
public:
    int startX;
    int endX;
    int startY;
    int endY;
    characterInfoRect(int x1, int y1, int x2, int y2) {
        startX = x1;
        startY = y1;
        endX = x2;
        endY = y2;
    }
    void drawAndPrintText(Character* ch) {
        Rect playerName = Rect(startX, startY, endX, startX + 2);
        playerName.draw();
        playerName.printText("人物介绍", "middle");

        //背景故事
        Rect blackStory = Rect(startX, startY + 2, startX + 24, endY);
        blackStory.draw();
        blackStory.printText(ch->backstory);

        //骰子选项
        Rect choose = Rect(startX + 24, startY + 2, endX, endY);
        choose.draw();
        string chChoose;//记录骰子
        for (int i = 0; i < 7; i++) {
            chChoose += to_string(ch->dice[i]);
            chChoose += " / ";
        }
        choose.printText(chChoose);


    }
};













//------------------------------------------------------------------//

//开始界面函数
void ShowBeginPage() {
    system("mode con cols=120 lines=30");
    //开始界面框
    Rect r1 = Rect(1, 1, 80, 30);
    r1.draw();

    //操作说明框
    Rect instruction = Rect(90, 1, 120, 30);
    instruction.draw();
    instruction.printText("操作说明：   在屏幕提示处输入相应的数字进入界面。如：1表示开始游戏，2表示历史排行，3表示游戏设置  ");
    //cout<<instruction.startX1<<endl;

    //游戏名框
    Rect gameName = Rect(11, 3, 70, 5);
    gameName.draw();
    gameName.printText("                     一起来看流星雨                     ");

    //画五角星
    DrawFive(3, 7);
    DrawFive(59, 7);

    //画开始游戏
    Rect beginGame = Rect(34, 7, 47, 9);
    beginGame.draw();
    beginGame.printText("  开始游戏 ");

    //画排行榜
    Rect rank = Rect(34, 9, 47, 11);
    rank.draw();
    rank.printText("  历史排行 ");

    //画游戏设置
    Rect setting = Rect(34, 11, 47, 13);
    setting.draw();
    setting.printText("  游戏设置 ");

    //画出品界面
    Rect sell = Rect(11, 25, 70, 27);
    sell.draw();
    sell.printText("                 从0开始的1世界荣誉出品                ");


    //设置命令行窗口大小
    //system("mode con cols=120 lines=30");
}

//输入玩家名界面
void inputPlayerNamePage() {
    system("mode con cols=50 lines=10");
    cout << "请输入您的玩家名：  ";
    //std::string player_name;
    getline(cin, player_name);


}




//排行榜界面
void ShowRankPage(int source) {
    system("mode con cols=120 lines=30");
    if (source == 1 || !source) {
        //最上方长条
        Rect historyRank = Rect(11, 3, 110, 5);
        historyRank.draw();
        historyRank.printText("您的历史排行榜", "middle");

        //三个竖条 宽度26，间距11
        Rect long1 = Rect(11, 6, 36, 26);
        long1.draw();
        long1.printText("第一名", "middle");
        Rect long2 = Rect(48, 6, 48 + 25, 26);
        long2.draw();
        Rect long3 = Rect(48 + 12 + 25, 6, 110, 26);
        long3.draw();

        Rect last = Rect(52, 27, 67, 29);
        last.draw();
        if (!source) last.printText("返回", "middle");
        else last.printText("是否再来一局", "middle");
    }
    else cout << "wrong parameters" << endl;
}

//人物角色画面
int ShowCharacterPage(int n, Character* cha[]) {
    system("mode con cols=120 lines=30");
   
    int ch_id;//记录确定选择的角色的编号
    characterListRect clr = characterListRect(2, 2, 21, 20, 9);//画九个竖着的格子，第一个不放人物名
    clr.drawAndPrintText(n, cha);
    gotoXY(clr.startX + 8, clr.startY + 1);
    int x = clr.startX + 8;
    int y = clr.startY + 1;
    characterInfoRect cir = characterInfoRect(34, 10, 74, 18);//初始化人物信息栏
    while (true) {
        int k = _kbhit();//判断键盘是否有输入
        if (k) {//如果有敲击返回1
            char c = (char)_getch();
            if ('s' == c) {
                y += 2;
                gotoXY(x, y);
            }
            else if ('w' == c) {
                y -= 2;
                gotoXY(x, y);
            }

            switch ((y - 3) >> 1)
            {
            case 1:
                cir.drawAndPrintText(cha[1]);
                break;
            case 2:
                cir.drawAndPrintText(cha[2]);
                break;
            case 3:
                cir.drawAndPrintText(cha[3]);
                break;
            case 4:
                cir.drawAndPrintText(cha[4]);
                break;
            case 5:
                cir.drawAndPrintText(cha[5]);
                break;
            case 6:
                cir.drawAndPrintText(cha[6]);
                break;
            case 7:
                cir.drawAndPrintText(cha[7]);
                break;
            case 8:
                cir.drawAndPrintText(cha[8]);
                break;
            default:
                break;
            }
            if (c == '\n') {
                ch_id = (y - 3) >> 1;
                break;
            }

        }
    }
    return ch_id;

}


//游戏地图画面
void ShowGamePage() {
    system("mode con cols=182 lines=52");
    Rect mapBoard = Rect(2, 2, 181, 51);
    mapBoard.draw();

    //事件格子6*4
    int beginX = 56;
    int beginY = 12;

    //开始画地图
    horizontalRectMadeByRect h1 = horizontalRectMadeByRect(81, 12, 116, 15, 7);
    h1.drawAndPrintText(7, "前有滚石遭遇土匪        牢底坐穿        遭遇土匪        ");
    horizontalRectMadeByRect h2 = horizontalRectMadeByRect(56, 15, 86, 18, 6);
    h2.drawAndPrintText(6, "前有滚石        牢底坐穿                十字岔口");
    horizontalRectMadeByRect h3 = horizontalRectMadeByRect(56, 30, 96, 33, 8);
    h3.drawAndPrintText(8, "挖宝地点十字岔口十字岔口十字岔口                流星雨          ");
    horizontalRectMadeByRect h4 = horizontalRectMadeByRect(66, 21, 86, 24, 4);
    h4.drawAndPrintText(4, "挖宝地点牢底坐穿        传送门  ");
    horizontalRectMadeByRect h5 = horizontalRectMadeByRect(101, 30, 126, 33, 5);
    h5.drawAndPrintText(5, "牢底坐穿        路过起点        前有滚石");
    horizontalRectMadeByRect h6 = horizontalRectMadeByRect(56, 39, 76, 42, 4);
    h6.drawAndPrintText(4, "        十字岔口        十字岔口");
    horizontalRectMadeByRect h7 = horizontalRectMadeByRect(56, 45, 126, 48, 14);
    h7.drawAndPrintText(14, "挖宝地点流星雨          遭遇土匪挖宝地点        流星雨          挖宝地点        十字岔口                        ");
    horizontalRectMadeByRect h8 = horizontalRectMadeByRect(71, 36, 96, 39, 5);
    h8.drawAndPrintText(5, "                                挖宝地点");
    horizontalRectMadeByRect h9 = horizontalRectMadeByRect(101, 36, 116, 39, 3);
    h9.drawAndPrintText(3, "        十字岔口        ");



    //画竖线
    verticalRectMadeByRect v0 = verticalRectMadeByRect(56, 39, 61, 48, 3);
    v0.drawAndPrintText(3, "        遭遇土匪挖宝地点");
    verticalRectMadeByRect v1 = verticalRectMadeByRect(56, 15, 61, 33, 6);
    v1.drawAndPrintText(6, "前有滚石遭遇土匪牢底坐穿遭遇土匪传送门  挖宝地点");
    verticalRectMadeByRect v2 = verticalRectMadeByRect(66, 21, 71, 33, 4);
    v2.drawAndPrintText(4, "挖宝地点                十字岔口");
    verticalRectMadeByRect v3 = verticalRectMadeByRect(111, 12, 116, 39, 9);
    v3.drawAndPrintText(9, "        挖宝地点挖宝地点挖宝地点挖宝地点        路过起点                ");
    verticalRectMadeByRect v4 = verticalRectMadeByRect(121, 30, 126, 48, 6);
    v4.drawAndPrintText(6, "前有滚石传送门          流星雨                  ");
    verticalRectMadeByRect v5 = verticalRectMadeByRect(101, 30, 106, 39, 3);
    v5.drawAndPrintText(3, "牢底坐穿                ");
    verticalRectMadeByRect v6 = verticalRectMadeByRect(91, 30, 96, 48, 6);
    v6.drawAndPrintText(6, "                挖宝地点牢底坐穿                ");
    verticalRectMadeByRect v7 = verticalRectMadeByRect(81, 36, 86, 48, 4);
    v7.drawAndPrintText(4, "                传送门          ");
    verticalRectMadeByRect v8 = verticalRectMadeByRect(71, 30, 76, 48, 6);
    v8.drawAndPrintText(6, "十字岔口                十字岔口        遭遇土匪");
    verticalRectMadeByRect v9 = verticalRectMadeByRect(81, 12, 86, 33, 7);
    v9.drawAndPrintText(7, "前有滚石十字岔口        传送门          牢底坐穿        ");
    verticalRectMadeByRect v10 = verticalRectMadeByRect(106, 39, 111, 45, 2);
    v10.draw();


    //画玩家信息
    playerRect p1 = playerRect(5, 5, 54, 24);
    p1.draw();

    playerRect p2 = playerRect(5, 28, 54, 47);
    p2.draw();

    playerRect p3 = playerRect(129, 5, 178, 24);
    p3.draw();

    playerRect p4 = playerRect(129, 28, 178, 47);
    p4.draw();



    //画局内排名信息
    localRankRect lrr = localRankRect(76, 4, 106, 7, 6);
    lrr.draw();
    int a[4] = { 2,3,4,1 };
    lrr.drawAndPrintText(29, 10, a);




}

void ShowSettingPage() {
    system("mode con cols=120 lines=30");
    Rect setting = Rect(20, 10, 100, 25);
    setting.draw();
    setting.printText("this is setting page", "middle");
}

